package com.example.service;

import com.example.pojo.SysRole;
import com.example.pojo.SysUser;
import com.example.repository.SysUserRepository;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * UserDetailsService :spring security提供的一个自定义认证接口
 */
@Component(value = "userDetailsService")
public class MyUserDetailsService implements UserDetailsService {

    @Resource
    private SysUserRepository sysUserRepository;

    /**
     * 通过用户名进行认证信息的查询
     * 通过数据库查询用户信息以及用户的角色信息，将其封装到UserDetails对象中并返回
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        //获取用户信息
        SysUser sysUser = sysUserRepository.findByUsername(username);

        if (Objects.isNull(sysUser)) {
            throw new UsernameNotFoundException("用户不存在.........");
        }
        //获取角色信息
        List<SysRole> roles = sysUser.getRoles();
        //自定义权限列表
        List<GrantedAuthority> authorities = new ArrayList<>();
        if (Objects.nonNull(roles) && roles.size() != 0) {
            for (SysRole role : roles) {
                String name = role.getRole();
                //基于角色一个权限管理，默认会在角色名前添加ROLE_
                authorities.add(new SimpleGrantedAuthority("ROLE_" + name));
            }
        }
        //最终将用户数据以及用户的权限列表封装到User对象中并返回
        User user = new User(username, sysUser.getPassword(), sysUser.getEnabled(),
                true, true, true, authorities);
        return user;
    }
}
